﻿using Mapster;
using Microsoft.AspNetCore.Mvc;
using RuoVea.DynamicWebApi;
using RuoVea.ExDto;
using RuoVea.ExSugar;
using RuoVea.ExSugar.Entity;
using RuoVea.OmiApi.Log.Entitys;
using RuoVea.OmiApi.Log.Service.Dto;
using SqlSugar;
using System.ComponentModel;


namespace RuoVea.OmiApi.Log.Service;

/// <summary>
/// 操作日志服务 🔷
/// </summary>
[ApiExplorerSettings(GroupName = "system")]
public class SysLogOpService : IApplicationService
{
    private readonly SugarRepository<SysLogOp> _thisRepository;

    /// <summary>
    /// 操作日志服务
    /// </summary>
    /// <param name="thisRepository"></param>
    public SysLogOpService(SugarRepository<SysLogOp> thisRepository) => _thisRepository = thisRepository;

    /// <summary>
    /// 分页查询操作日志🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<PageResult<SysLogOpDto>> GetPagesAsync([FromQuery] SysLogOpParam data)
    {
        // 处理结束时间，如果结束时间有值，设置为当天的23:59:59
        DateTime? endTime = data.EndTime;
        if (endTime.HasValue)
        {
            endTime = endTime.Value.Date.AddDays(1).AddSeconds(-1);
        }

        var query = _thisRepository.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(data.Name?.Trim()), u => u.Name.Contains(data.Name.Trim()))
            .WhereIF(data.Success.HasValue, u => u.Success == data.Success.Value)
            .WhereIF(!string.IsNullOrEmpty(data.ReqMethod?.Trim()), u => u.ReqMethod == data.ReqMethod.Trim())
            .WhereIF(data.BeginTime.HasValue, u => u.OpTime >= data.BeginTime.Value)
            .WhereIF(endTime.HasValue, u => u.OpTime <= endTime.Value);

        // 安全的排序处理
        if (!string.IsNullOrWhiteSpace(data.Sidx))
        {
            var sortOrder = "asc";
            if (!string.IsNullOrWhiteSpace(data.Sord) && data.Sord.Equals("desc", StringComparison.OrdinalIgnoreCase))
            {
                sortOrder = "desc";
            }

            // 使用安全的字段名映射，防止SQL注入
            var safeOrderBy = GetSafeOrderByField(data.Sidx);
            query = query.OrderBy($"{safeOrderBy} {sortOrder}");
        }
        else
        {
            query = query.OrderBy(u => u.OpTime, OrderByType.Desc);
        }

        return await query.ToPageAsync<SysLogOp, SysLogOpDto>(data.PageNo, data.PageSize);
    }

    /// <summary>
    /// 安全的排序字段映射（防止SQL注入）
    /// </summary>
    private string GetSafeOrderByField(string fieldName)
    {
        // 定义允许排序的字段白名单（基于实际实体字段）
        var allowedFields = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
        {
            ["id"] = "Id",
            ["name"] = "Name",
            ["success"] = "Success",
            ["message"] = "Message",
            ["ip"] = "Ip",
            ["location"] = "Location",
            ["browser"] = "Browser",
            ["os"] = "Os",
            ["url"] = "Url",
            ["classname"] = "ClassName",
            ["methodname"] = "MethodName",
            ["reqmethod"] = "ReqMethod",
            ["param"] = "Param",
            ["result"] = "Result",
            ["elapsedtime"] = "ElapsedTime",
            ["optime"] = "OpTime",
            ["account"] = "Account",
            ["createtime"] = "CreateTime"
        };

        return allowedFields.TryGetValue(fieldName.ToLower(), out var safeField)
            ? safeField
            : "OpTime"; // 默认按操作时间排序
    }


    /// <summary>
    /// 根据主键查询🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<SysLogOpDto> GetDataAsync([FromQuery] EntityBaseId data)
    {
        var model = await _thisRepository.GetByIdAsync(data.Id);
        return model.Adapt<SysLogOpDto>();
    }
    /// <summary>
    /// 清空异常日志🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task<bool> DeleteDataAsync([FromBody] EntityBaseId data) => await _thisRepository.DeleteAsync(m => data.Id == m.Id);

    /// <summary>
    /// 清空操作日志 🔖
    /// </summary>
    /// <returns></returns>
    [HttpDelete]
    [DisplayName("清空操作日志")]
    public bool Clear()
    {
       return _thisRepository.AsSugarClient().DbMaintenance.TruncateTable<SysLogOp>();
    }

    /// <summary>
    /// 按时间范围删除操作日志
    /// </summary>
    [HttpDelete("clear-by-time")]
    [DisplayName("按时间范围删除操作日志")]
    public async Task<int> ClearByTimeRange([FromQuery] DateTime? beginTime, [FromQuery] DateTime? endTime)
    {
        if (beginTime == null && endTime == null)
            throw new ArgumentException("请至少提供一个时间条件");

        // 处理结束时间
        DateTime? processedEndTime = endTime;
        if (processedEndTime.HasValue)
        {
            processedEndTime = processedEndTime.Value.Date.AddDays(1).AddSeconds(-1);
        }

        return await _thisRepository.AsDeleteable()
            .WhereIF(beginTime.HasValue, u => u.OpTime >= beginTime.Value)
            .WhereIF(processedEndTime.HasValue, u => u.OpTime <= processedEndTime.Value)
            .ExecuteCommandAsync();
    }

    /// <summary>
    /// 批量删除操作日志
    /// </summary>
    [HttpPost("batch-delete")]
    [DisplayName("批量删除操作日志")]
    public async Task<bool> BatchDelete([FromBody] List<long> ids)
    {
        if (ids == null || !ids.Any())
            throw new ArgumentException("请提供要删除的日志ID");

        return await _thisRepository.DeleteAsync(u => ids.Contains(u.Id));
    }
}

